﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using nyxwin.Main.Base.ViewModels;
using nyxwin.Common.Settings;
using nyxwin.Data.Mail;
using System.Collections.Generic;
using nyxwin.Data.Bookmarks;
using nyxwin.Main.ViewModel.SubModels;
using System.Linq;

namespace nyxwin.Main.ViewModel.Main
{
    public class BookMarkViewModel : PivotItemViewModel
    {
        private static readonly Guid GETTINGBOOKMARKS_ID = Guid.NewGuid();

        private AppBarButton _refreshButton;

        public BookMarkViewModel()
        {
            _bookmarkCategories = new List<BookMarkCategoryModel>();

            _refreshButton = new AppBarButton(new Uri("/Icons/refresh.png", UriKind.Relative), () => Refresh())
            {
                IsEnabled = true
            };

            ActualizeAppBarTitles();
        }

        public override IEnumerable<AppBarButton> AppBarButtons
        {
            get
            {
                yield return _refreshButton;
            }
        }

        private void ActualizeAppBarTitles()
        {
            _refreshButton.Title = Localization.GetString("RefreshButtonTitle");
        }

        protected override void OnLocalizationChanged()
        {
            base.OnLocalizationChanged();

            ActualizeAppBarTitles();
            RaisePropertyChanged(() => Title);
        }

        public override string Title
        {
            get
            {
                return Localization.GetString("BookMarkTitle");
            }
        }

        private void Refresh()
        {
            SetIsInDeterminate(GETTINGBOOKMARKS_ID, Localization.GetString("GettingBookMarks"));

            var bookmarksMgr = new BookmarksManager(ApplicationSettings.Instance.AuthorizationNick, ApplicationSettings.Instance.AuthorizationToken);

            bookmarksMgr.ErrorOccurred +=
                (evSender, evArgs) => Dispatcher.BeginInvoke(() =>
                {
                    UnSetInDeterminate(GETTINGBOOKMARKS_ID);
                    RaiseError(evArgs.ErrorMessage);
                });

            bookmarksMgr.GetBookmarksCompleted +=
                (evSender, evArgs) => Dispatcher.BeginInvoke(delegate
                {
                    UnSetInDeterminate(GETTINGBOOKMARKS_ID);

                    if (evArgs.Error)
                    {
                        RaiseError(evArgs.ErrorMessage);
                    }
                    else
                    {
                        UpdateBookMarks(evArgs.BookmarkList);
                    }
                });

            bookmarksMgr.GetBookmarks(BookmarksTypeEnum.All);
        }

        private void UpdateBookMarks(List<Bookmark> list)
        {
            if (list == null)
            {
                BookMarkCategories = new List<BookMarkCategoryModel>();
            }
            else
            {
                var categories = list
                    .Where(x => x.DiscussionId == -1)
                    .ToList();

                var deleted = _bookmarkCategories
                    .Where(x => !categories
                        .Select(y => y.CategoryId)
                        .Where(y => y != null)
                        .Select(y => y.Value)
                        .Contains(x.CategoryId)
                    );

                var added = categories
                    .Where(x => x.CategoryId.HasValue)
                    .Where(x => !_bookmarkCategories
                        .Select(y => y.CategoryId)
                        .Contains(x.CategoryId.Value)
                    );

                if (deleted.Count() == 0 && added.Count() == 0)
                {
                    foreach (var cat in _bookmarkCategories)
                    {
                        UpdateCategory(cat, list);
                    }
                }
                else
                {
                    ClearAndInitCategories(categories, list);
                }
            }
        }

        private void UpdateCategory(BookMarkCategoryModel cat, List<Bookmark> list)
        {
            var orCat = list
                .Where(x => x.DiscussionId == -1)
                .Where(x => x.CategoryId.HasValue)
                .FirstOrDefault(x => x.CategoryId == cat.CategoryId);

            if (orCat != null)
            {
                cat.Title = orCat.Title;
                cat.SetBookMarks(list
                    .Where(x => x.CategoryId == cat.CategoryId)
                    .Where(x => x.DiscussionId != -1)
                    .ToList()
                );
            }
        }

        private void ClearAndInitCategories(List<Bookmark> categories, List<Bookmark> list)
        {
            foreach (var cat in _bookmarkCategories)
            {
                cat.Unload();
            }

            BookMarkCategories = categories.Select(x => new BookMarkCategoryModel(x)).ToList();

            foreach (var cat in _bookmarkCategories)
            {
                UpdateCategory(cat, list);
            }
        }

        private List<BookMarkCategoryModel> _bookmarkCategories;

        public List<BookMarkCategoryModel> BookMarkCategories
        {
            get { return _bookmarkCategories; }
            set
            {
                _bookmarkCategories = value;
                RaisePropertyChanged(() => BookMarkCategories);
            }
        }

        public override void Enter()
        {
            Refresh(); // TODO: ++juraj: this isn't good idea, please use caching somehow.
        }
    }
}
